package pl.edu.pw.ee.buildcity.scheduler;

import org.fest.assertions.Fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.BDDMockito.*;

/**
 * @author mgrzechocinski
 * @since 2009-10-11
 */
@RunWith(MockitoJUnitRunner.class)
public class BuildCitySchedulerTestCase {

	@Mock
	private Scheduler mockScheduler;

	@Test
	public void shouldWrapExceptionWhileAddingJob() throws SchedulerException {
		//Given
		BuildCityJobDetail buildCityJobDetail = new BuildCityJobDetail("testJob");
		willThrow(new SchedulerException("error msg")).given(mockScheduler).addJob(buildCityJobDetail, true);

		//When
		BuildCitySchedulerImpl schedulerImpl = new BuildCitySchedulerImpl(mockScheduler, null);
		try {
			schedulerImpl.save(buildCityJobDetail);
			Fail.fail("SchedulerRuntimeException should be thrown");
		} catch (SchedulerRuntimeException e) {
			//Then
			assertThat(e.getCause()).isInstanceOf(SchedulerException.class);
		}
		verify(mockScheduler).addJob(buildCityJobDetail, true);
	}

	@Test
	public void shouldWrapExceptionWhileGettingJob() throws SchedulerException {
		//Given
		given(mockScheduler.getJobDetail("testJob", BuildCityJobDetail.DEFAULT_JOBS_GROUP)).willThrow(new SchedulerException("error msg"));

		//When
		BuildCitySchedulerImpl schedulerImpl = new BuildCitySchedulerImpl(mockScheduler, null);
		try {
			schedulerImpl.getJobDetail("testJob");
			Fail.fail("SchedulerRuntimeException should be thrown");
		} catch (SchedulerRuntimeException e) {
			//Then
			assertThat(e.getCause()).isInstanceOf(SchedulerException.class);
		}
		verify(mockScheduler).getJobDetail("testJob", BuildCityJobDetail.DEFAULT_JOBS_GROUP);
	}

	@Test
	public void shouldThrowExceptionWhenJobNotFound() throws SchedulerException {
		//Given
		given(mockScheduler.getJobDetail("testJob", BuildCityJobDetail.DEFAULT_JOBS_GROUP)).willReturn(null);

		//When
		BuildCitySchedulerImpl schedulerImpl = new BuildCitySchedulerImpl(mockScheduler, null);
		try {
			schedulerImpl.getJobDetail("testJob");
			Fail.fail("SchedulerRuntimeException should be thrown");
		} catch (SchedulerRuntimeException e) {
			//Then
			assertThat(e.getMessage()).isEqualTo("BuildCityJobDetail 'testJob' not found");
		}
		verify(mockScheduler).getJobDetail("testJob", BuildCityJobDetail.DEFAULT_JOBS_GROUP);
	}

	@Test
	public void shouldThrowExceptionWhenFoundJobIsInstanceOfDifferentClass() throws SchedulerException {
		//Given
		given(mockScheduler.getJobDetail("testJob", BuildCityJobDetail.DEFAULT_JOBS_GROUP)).willReturn(new JobDetail());

		//When
		BuildCitySchedulerImpl schedulerImpl = new BuildCitySchedulerImpl(mockScheduler, null);
		try {
			schedulerImpl.getJobDetail("testJob");
			Fail.fail("SchedulerRuntimeException should be thrown");
		} catch (SchedulerRuntimeException e) {
			//Then
			assertThat(e.getMessage()).isEqualTo("BuildCityJobDetail 'testJob' not found");
		}
		verify(mockScheduler).getJobDetail("testJob", BuildCityJobDetail.DEFAULT_JOBS_GROUP);
	}
}
